/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

import java.util.*;
import java.io.*;
import java.text.*;
import javax.swing.*;

/**
 * <p> Represents a single process event (audit trail entry).
 *
 * @author Andriy Nikolov
 * @version 1.0
 */
public class ProcessEvent implements TimestampOwner {

  ProcessTask task;
  Date eventTime;
  String originator;
  ProcessEventType eventType;
  EMailMessage eMailMessage;

  public ProcessEvent() {
  }

  /**
   * Creates a ProcessEvent instance related to a given task.
   *
   * @param task ProcessTask
   */
  public ProcessEvent(ProcessTask task) {
    this.task = task;
  }

  /**
   * Creates a ProcessEvent instance related to a given task and links it to a
   * message.
   *
   * @param task ProcessTask
   * @param message EMailMessage
   */
  public ProcessEvent(ProcessTask task, EMailMessage message) {
    this.task = task;
    this.eMailMessage = message;
  }

  public ProcessTask getTask() {
    return task;
  }

  public void setTask(ProcessTask value) {
    task = value;
  }

  /**
   * Sets the event time.
   *
   * @param time Date
   */
  public void setTime(Date time) {
    eventTime = time;
  }

  public Date getTime() {
    return eventTime;
  }

  /**
   * Links the event to a message.
   *
   * @param message EMailMessage
   */
  public void setEMailMessage(EMailMessage message) {
    this.eMailMessage = message;
  }

  public EMailMessage getEMailMessage() {
    return eMailMessage;
  }

  /**
   * Sets the originator of the event.
   *
   * @param name String
   */
  public void setOriginator(String name) {
    originator = name;
  }

  public String getOriginator() {
    return originator;
  }

  public ProcessEventType getType() {
    return eventType;
  }

  /**
   * Sets the event type.
   *
   * @param type ProcessEventType
   */
  public void setType(ProcessEventType type) {
    eventType = type;
  }

  /**
   * Gets the event's date and time. The same as getTime().
   *
   * @return Date
   */
  public Date getTimestamp() {
    return eventTime;
  }

  /**
   * Saves the audit trail entry into the writer. Called only by the
   * higher-level objects (ProcessLog and ProcessCase).
   *
   * @param writer PrintWriter
   */
  public void save(PrintWriter writer) {
    char sign;
    long offset;
    EMailRecipient iterPerson;
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
    SimpleDateFormat offsetFormat = new SimpleDateFormat("hh:mm");
    offset = sdf.getCalendar().get(Calendar.ZONE_OFFSET);
    Date d = new Date(-offset+Math.abs(offset));
    sign = (offset>=0)?('+'):('-');
//    SimpleTimeZone stz = new SimpleTimeZone(sdf.getTimeZone().getRawOffset(), "");
//    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
    writer.println("<AuditTrailEntry>");
    if(task.getCase().getProcessLog().hasToSaveMessageData()) {
      writer.println("<Data>");
      writer.print("<Attribute name=\"subject\">");
      writer.print(refineString(eMailMessage.getSubject()));
      writer.println("</Attribute>");
      writer.print("<Attribute name=\"from\">");
      writer.print(refineString(eMailMessage.getFrom().getName()));
      writer.println("</Attribute>");
      if(eMailMessage.getTo().size()>0) {
        writer.print("<Attribute name=\"to\">");
        for (int i = 0; i < eMailMessage.getTo().size(); i++) {
          iterPerson = (EMailRecipient) eMailMessage.getTo().get(i);
          if(i>0) {
            writer.print(";");
          }
          writer.print(refineString(iterPerson.getName()));
        }
        writer.println("</Attribute>");
      }
      if(eMailMessage.getCc().size()>0) {
        writer.print("<Attribute name=\"cc\">");
        for (int i = 0; i < eMailMessage.getCc().size(); i++) {
          iterPerson = (EMailRecipient) eMailMessage.getCc().get(i);
          if(i>0) {
            writer.print(";");
          }
          writer.print(refineString(iterPerson.getName()));
        }
        writer.println("</Attribute>");
      }
      if(eMailMessage.getBcc().size()>0) {
        writer.print("<Attribute name=\"bcc\">");
        for (int i = 0; i < eMailMessage.getBcc().size(); i++) {
          iterPerson = (EMailRecipient)eMailMessage.getBcc().get(i);
          if (i > 0) {
            writer.print(";");
          }
          writer.print(refineString(iterPerson.getName()));
        }
        writer.println("</Attribute>");
      }
      writer.println("</Data>");
    }
    writer.print("<WorkflowModelElement>");
    writer.print(refineString(task.getName()));
    writer.println("</WorkflowModelElement>");
    writer.print("<EventType");
    if(eventType.getStandardName().equals("unknown")) {
      writer.print(" unknowntype=\""+refineString(eventType.getAliasName())+"\" ");
    }
    writer.print(">");
    writer.print(refineString(eventType.getStandardName()));
    writer.println("</EventType>");
    writer.print("<Timestamp>");
    writer.print(sdf.format(eventTime)+sign+offsetFormat.format(d));
    writer.println("</Timestamp>");
    writer.print("<Originator>");
    writer.print(refineString(originator));
    writer.println("</Originator>");
    writer.println("</AuditTrailEntry>");
  }

  public void write(JTextArea textArea) {
    textArea.append(task.getName()+" "+eventType.getAliasName()+"\n");
  }

  private String refineString(String str) {
    String tmp = str;
    if(tmp==null)
      return "";
    tmp = tmp.replaceAll("&", "&amp;");
    tmp = tmp.replaceAll("<", "&lt;");
    tmp = tmp.replaceAll(">", "&gt;");
    tmp = tmp.replaceAll("\"", "&quot;");
    tmp = tmp.replaceAll("\'", "&apos;");
    return tmp;
  }

}
